package assignment;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


import com.myprofile.profile.MuseumItem;
import com.myprofile.profile.ProfileType;

import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;

public class TourAgent extends Agent {

	private AID curatorAgent;
	private String publicMsgString;
	private Map<AID, ArrayList<Item>> usedItems;
	//private ArrayList<String> itemInner = new ArrayList<String>(2);
	private ArrayList<ArrayList<String>> itemString = new ArrayList<ArrayList<String>>(15);

	
	protected void setup() {
		usedItems = new HashMap<AID, ArrayList<Item>>();
		// Register the guide service in the yellow pages
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(getAID());
		ServiceDescription sd = new ServiceDescription();
		sd.setType("Guide");
		sd.setName("TourGuide");
		dfd.addServices(sd);
		try {
			DFService.register(this, dfd);
		} catch (FIPAException fe) {
			fe.printStackTrace();
		}

		// Look for Curator services
		DFAgentDescription template = new DFAgentDescription();
		ServiceDescription sd2 = new ServiceDescription();
		sd2.setType("Curator");
		template.addServices(sd2);

		while (curatorAgent == null) {
			try {
				DFAgentDescription[] result = DFService.search(this, template);
				if (result.length > 0)
					curatorAgent = result[0].getName();
				// System.out.println(result[0].getName());
			} catch (FIPAException fe) {
				fe.printStackTrace();
			}
		}

		// Printout a welcome message
		System.out.println("Hallo! " + getAID().getLocalName() + " is here.");

		// Add behaviors
		// cyclic constantly looking for a message from Profiler
		this.addBehaviour(new CyclicBehaviour() {

			@Override
			public void action() {

				ProfileType prf = null;
				AID[] aid = new AID[1];
				aid[0] = getAID();
				MessageTemplate mt = MessageTemplate.and(
						MessageTemplate.MatchReceiver(aid),
						MessageTemplate.MatchPerformative(ACLMessage.CFP));
				ACLMessage msg = myAgent.receive(mt);
				if (msg != null) {
					AID userAID = msg.getSender();
					ArrayList<String> keywords = new ArrayList<String>(10);
					
					try {
						prf = ((ProfileType) msg.getContentObject());
						if(prf.getPrivacy()>=0.5  &&  prf.getPrivacy()<1){
						for (int i = 0; i < prf.getInterests().getInterest()
								.size(); i++){
							keywords.add(((ProfileType) msg.getContentObject())
									.getInterests().getInterest().get(i));
						}
						}else if(prf.getPrivacy()>=1){
							for (int i = 0; i < prf.getVisitedItems().getVisitedItem()
							.size(); i++){
								if(((ProfileType) msg.getContentObject()).getVisitedItems()
										.getVisitedItem().get(i).getRating()>4.0)
						keywords.add(((ProfileType) msg.getContentObject()).getVisitedItems()
								.getVisitedItem().get(i).getSubject());
					}
					}
						System.out.println("Makeing tour for " + keywords);
					} catch (UnreadableException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					}
					
					// Message received. process it
					if (!usedItems.containsKey(userAID)) {
						usedItems.put(userAID, new ArrayList<Item>());
						for (int i = 0; i < prf.getVisitedItems()
								.getVisitedItem().size(); i++) {
							MuseumItem mi = prf.getVisitedItems()
									.getVisitedItem().get(i);
							usedItems.get(userAID).add(
									new Item(mi.getId(), mi.getName(), mi
											.getSubject()));
						}
					}
					/*
					 * keywords. = msg.getContent();
					 * 
					 * ACLMessage reply = msg.createReply();
					 * reply.setPerformative(ACLMessage.PROPOSE);
					 * 
					 * System.out.println(myAgent.getLocalName()+" says: You like "
					 * + keyword);
					 */

					/*try {
						Thread.sleep(2000);
					} catch (InterruptedException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}*/
					// Pass on request to Curator
					ACLMessage msga = new ACLMessage(ACLMessage.REQUEST);

					msga.addReceiver(curatorAgent);
					System.out.print(myAgent.getLocalName()
							+ " found the following curator agents: ");

					System.out.println(curatorAgent.getLocalName());

					msga.setPerformative(ACLMessage.REQUEST);

					// keywords.add("optics");
					try {
						msga.setContentObject(keywords);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					myAgent.send(msga);
					// System.out.println("Msg1 sent");

					ACLMessage replyFCurator = null;
					MessageTemplate mt2 = MessageTemplate.and(
							MessageTemplate.MatchReceiver(aid),
							MessageTemplate.MatchPerformative(ACLMessage.PROPOSE));

					// Wait for response from Curator
					while (replyFCurator == null) {
						replyFCurator = myAgent.receive(mt2);
					}
					// publicMsgString=replyFCurator.getContent();

					ArrayList<Item> matchingItems = null;
					try {
						matchingItems = (ArrayList<Item>) replyFCurator
								.getContentObject();

					} catch (UnreadableException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}

					if (usedItems.get(userAID) != null) {
						for (int a = 0; a < usedItems.get(userAID).size(); a++)
							matchingItems.remove(usedItems.get(userAID).get(a));
					}
					matchingItems.trimToSize();
					while (matchingItems.size() > 15)
						matchingItems.remove(matchingItems.size() - 1);
					// new profiler

					for (Item i : matchingItems)
						usedItems.get(userAID).add(i);
					
					// System.out.println(matchingItems);
					
					for (Item i : matchingItems){
						ArrayList<String> al = new ArrayList<String>(2);
						al.add(i.getId());
						al.add(i.getTitle());
						itemString.add(al);
					}
					// Reply to Profiler
					ACLMessage reply = msg.createReply();
					reply.setPerformative(ACLMessage.PROPOSE);
					try {
						reply.setContentObject(itemString);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					myAgent.send(reply);
				}

			}

		});
	}
}
